package com.ict.txmsv2.controller.clockIn;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.RandomUtil;
import com.arcsoft.face.toolkit.ImageFactory;
import com.arcsoft.face.toolkit.ImageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import com.ict.txmsv2.enums.ErrorCodeEnum;
import com.ict.txmsv2.model.*;
import com.ict.txmsv2.services.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;

/**
 * @author yoleen
 * @date 2020/3/11 12:27
 */

@RestController
@RequestMapping("/clock/in/face")
public class FaceController {

    @Autowired
    FaceEngineService faceEngineService;
    @Autowired
    ClockInService clockInService;

    @Autowired
    UserFaceInfoService userFaceInfoService;

    @Autowired
    UserFaceService userFaceService;


    /**
     * 人脸添加
     *
     * @param registerFace
     * @return
     */
    @MethodDescrition("添加人脸")
    @PostMapping("/faceAdd")
    public Result<Object> faceAdd(@RequestBody RegisterFace registerFace, HttpServletRequest request) {
        String file = registerFace.getFile();
        String name = registerFace.getName();
        Integer groupId = registerFace.getGroupId();
        Integer userId = registerFace.getUserId();

        try {
            if (file == null || "".equals(file)) {
                return Results.newFailedResult("file is null");
            }
            if (groupId == null) {
                return Results.newFailedResult("groupId is null");
            }
            if (name == null || "".equals(name)) {
                return Results.newFailedResult("name is null");
            }
            if (userId == null) {
                return Results.newFailedResult("userId is null");
            }

            UserFaceInfo featureByUserId = userFaceService.getFeatureByUserId(userId);
            if (featureByUserId != null) {
                return Results.newFailedResult("请不要重复录入噢！");
            }
            byte[] decode = Base64.decode(base64Process(file));
            BufferedImage buffimg = ImageIO.read(new ByteArrayInputStream(decode));
            Graphics2D graphics = buffimg.createGraphics();
            graphics.drawImage(buffimg, 0, 0, null);
            graphics.setColor(new Color(251, 78, 60));
            Font font = new Font("宋体", Font.ITALIC, 16);
            graphics.setFont(font);
            graphics.drawString(registerFace.getGroupId() + "_" + registerFace.getName(), 10, 20);
//            String realpath = request.getServletContext().getRealPath("/img")+"/"+registerFace.getGroupId();
            String realpath = "D:\\txms\\img\\" + registerFace.getGroupId();
//            String realpath = "img/"+registerFace.getGroupId();
            File folder = new File(realpath);
            if (!folder.exists()) {
                folder.mkdirs();
            }

            ImageInfo imageInfo = ImageFactory.getRGBData(decode);

            //人脸特征获取
            byte[] bytes = faceEngineService.extractFaceFeature(imageInfo);
            if (bytes == null) {
                return Results.newFailedResult(ErrorCodeEnum.NO_FACE_DETECTED);
            }

            String fileName = registerFace.getGroupId() + "_" + registerFace.getName() + "_" + RandomUtil.randomString(5) + ".png";
            boolean flag = ImageIO.write(buffimg, "png", new File(folder, fileName));

            UserFaceInfo userFaceInfo = new UserFaceInfo();
            if (flag) {
                userFaceInfo.setFpath(folder + "\\" + fileName);
//                userFaceInfo.setFpath(folder+"/"+fileName);
            }
            userFaceInfo.setName(name);
            userFaceInfo.setGroupId(groupId);
            userFaceInfo.setFaceFeature(bytes);
            userFaceInfo.setFaceId(RandomUtil.randomString(10));

            //人脸特征插入到数据库
            userFaceInfoService.insertSelective(userFaceInfo);
            int maxId = userFaceInfoService.getMaxId();
            userFaceService.insertSelective(new UserFace(userId, maxId));
            return Results.newSuccessResult(null, "添加成功！");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Results.newFailedResult(ErrorCodeEnum.UNKNOWN);
    }


    /**
     * 人脸更新
     *
     * @param registerFace
     * @return
     */
    @MethodDescrition("更新人脸")
    @PutMapping("/faceUpdate")
    public Result<Object> faceUpdate(@RequestBody RegisterFace registerFace, HttpServletRequest request) {
        String file = registerFace.getFile();
        String name = registerFace.getName();
        Integer groupId = registerFace.getGroupId();
        Integer userId = registerFace.getUserId();

        try {
            if (file == null || "".equals(file)) {
                return Results.newFailedResult("file is null");
            }
            if (groupId == null) {
                return Results.newFailedResult("groupId is null");
            }
            if (name == null || "".equals(name)) {
                return Results.newFailedResult("name is null");
            }
            if (userId == null) {
                return Results.newFailedResult("userId is null");
            }

            byte[] decode = Base64.decode(base64Process(file));
            BufferedImage buffimg = ImageIO.read(new ByteArrayInputStream(decode));
            Graphics2D graphics = buffimg.createGraphics();
            graphics.drawImage(buffimg, 0, 0, null);
            graphics.setColor(new Color(251, 78, 60));
            Font font = new Font("宋体", Font.ITALIC, 16);
            graphics.setFont(font);
            graphics.drawString(registerFace.getGroupId() + "_" + registerFace.getName(), 10, 20);
//            String realpath = request.getServletContext().getRealPath("/img")+"/"+registerFace.getGroupId();
            String realpath = "D:\\txms\\img\\" + registerFace.getGroupId();
            File folder = new File(realpath);
            if (!folder.exists()) {
                folder.mkdirs();
            }
            ImageInfo imageInfo = ImageFactory.getRGBData(decode);

            //人脸特征获取
            byte[] bytes = faceEngineService.extractFaceFeature(imageInfo);
            if (bytes == null) {
                return Results.newFailedResult(ErrorCodeEnum.NO_FACE_DETECTED);
            }
            UserFaceInfo userFaceInfo = userFaceInfoService.getUserFaceInfoByUserId(userId);
            if (userFaceInfo == null) {
                return Results.newFailedResult("数据库中没有你的面容信息");
            }
            if (!faceEngineService.compareFeatureForOne(bytes, userFaceInfo.getFaceFeature())) {
                return Results.newFailedResult("系统怀疑你整容了，更新失败！");
            }

            String fileName = registerFace.getGroupId() + "_" + registerFace.getName() + "_" + RandomUtil.randomString(5) + ".png";
            boolean flag = ImageIO.write(buffimg, "png", new File(folder, fileName));

            String fpath = userFaceInfo.getFpath();
            if (fpath != null && !"".equals(fpath)) {
                File file1 = new File(fpath);
                boolean delete = file1.delete();
                if (delete && flag) {
                    userFaceInfo.setFpath(folder + "\\" + fileName);
//                    userFaceInfo.setFpath(folder+"/"+fileName);
                }
            }
            userFaceInfo.setName(name);
            userFaceInfo.setGroupId(groupId);
            userFaceInfo.setFaceFeature(bytes);
//            userFaceInfo.setId(registerFace.getFaceId());

            //人脸特征插入到数据库
            userFaceInfoService.updateByPrimaryKeySelective(userFaceInfo);
            return Results.newSuccessResult(userFaceInfoService.getMaxId(), "更新成功！");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Results.newFailedResult(ErrorCodeEnum.UNKNOWN);
    }

    /**
     * 人脸比对
     *
     * @param faceSearch
     * @return
     * @throws Exception
     */
    @MethodDescrition("人脸比对")
    @PostMapping("/faceCompare")
    public Result<Object> faceCompare(@RequestBody FaceSearch faceSearch) throws Exception {
        Integer groupId = faceSearch.getGroupId();
        String file = faceSearch.getFile();
        Integer userId = faceSearch.getUserId();
        if (groupId == null) {
            return Results.newFailedResult("groupId is null");
        }
        if (file == null || "".equals(file)) {
            return Results.newFailedResult("file is null");
        }
        if (userId == null) {
            return Results.newFailedResult("userId is null");
        }
        byte[] decode = Base64.decode(base64Process(file));
        BufferedImage bufImage = ImageIO.read(new ByteArrayInputStream(decode));
        ImageInfo imageInfo = ImageFactory.bufferedImage2ImageInfo(bufImage);


        //人脸特征获取
        byte[] bytes = faceEngineService.extractFaceFeature(imageInfo);
        if (bytes == null) {
            return Results.newFailedResult(ErrorCodeEnum.NO_FACE_DETECTED);
        }
        //根据userId获取数据库中的人脸特征
        UserFaceInfo userFaceInfo = userFaceService.getFeatureByUserId(userId);
        if (userFaceInfo == null) {
            return Results.newFailedResult("数据库中没有你的面容信息");
        }
        if (faceEngineService.compareFeatureForOne(bytes, userFaceInfo.getFaceFeature())) {
            if (clockInService.insert(new ClockIn(userId, "人脸识别")) == 1) {
                //根据userId去查你今天打卡次数
                int count = clockInService.count(userId);
                if (count % 2 == 1) {
                    return Results.newSuccessResult(null, userFaceInfo.getName() + "同学，欢迎你回来上班^_^");
                } else {
                    return Results.newSuccessResult(null, "下班打卡成功，bye~");
                }
            }
            return Results.newFailedResult("打卡失败了呢，请打一顿后台程序猿");
        }
        return Results.newFailedResult("？？？你是" + userFaceInfo.getName() + " ？？？");
    }

    private String base64Process(String base64Str) {
        if (!StringUtils.isEmpty(base64Str)) {
            String photoBase64 = base64Str.substring(0, 30).toLowerCase();
            int indexOf = photoBase64.indexOf("base64,");
            if (indexOf > 0) {
                base64Str = base64Str.substring(indexOf + 7);
            }

            return base64Str;
        } else {
            return "";
        }
    }
}
